package com.kl.model.pojo;

import com.kl.App;
import com.kl.TankGame;
import com.kl.constant.TankModel;
import com.kl.enums.Direct;
import com.kl.enums.TankType;
import com.kl.exceptions.DeathException;
import com.kl.model.base.AbstractAttack;
import com.kl.utils.CollectionUtils;
import lombok.Data;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.atomic.AtomicInteger;

import static com.kl.constant.AttackModel.DEFAULT_INSTANCE;
import static com.kl.constant.AttackModel.DEFAULT_SPEED;
import static com.kl.constant.Windows.HEIGHT;
import static com.kl.constant.Windows.WIDTH;
import static com.kl.enums.State.ALIVE;
import static com.kl.enums.State.DEATH;

/**
 * @author CC
 * time 2024-05-14
 * description
 *  攻击方式：子弹射击
 *  每一次攻击对于一个线程
 */
@Data
public class Shoot extends AbstractAttack{

    public Shoot(int x,int y,Direct direct,TankType origin){
        super(direct, ALIVE,x,y, DEFAULT_SPEED,origin);
    }

    @Override
    public boolean attack(int x, int y, Direct direct, Object object, TankType origin) {
        if (isDestroyed()) {
            throw new DeathException();
        }
        if (!CollectionUtils.isEmpty(((ArrayList<Tank>) object))) {
            ArrayList<Tank> target = (ArrayList<Tank>) object;
            Iterator<Tank> iterator = target.iterator();
            while (iterator.hasNext()) {
                Tank tank = iterator.next();
                if (tank.isDestroyed()) {
                    continue;
                }
                if(x > tank.getX()- TankModel.BODY_HALF_SIZE && x< tank.getX()+TankModel.BODY_HALF_SIZE &&
                        y>tank.getY()-TankModel.BODY_HALF_SIZE && y<tank.getY()+TankModel.BODY_HALF_SIZE
                ){
                    tank.setStatus(DEATH);
                    App.getEXPLODES().add(new Explode(tank.getY()-TankModel.BODY_HALF_SIZE, tank.getX()-TankModel.BODY_HALF_SIZE));
                    this.setState(DEATH);
                    return true;
                }
            }
        }
        return false;
    }
    @Override
    public void run() {
        AtomicInteger count = new AtomicInteger(0);
        outer:while (!isDestroyed()){
            if(count.get()>=DEFAULT_INSTANCE){
                this.setState(DEATH);
                break;
            }
            //子弹移动
            switch (getDirect()){
                case UP:
                    if(getY()-DEFAULT_SPEED >0){
                        this.setY(getY()- DEFAULT_SPEED);
                    }else {
                        this.setState(DEATH);
                        break outer;
                    }
                    break;
                case DOWN:
                    if(getY()+ DEFAULT_SPEED < HEIGHT){
                        this.setY(getY()+DEFAULT_SPEED);
                    }else {
                        this.setState(DEATH);
                        break outer;
                    }
                    break;
                case LEFT:
                    if(getX()- DEFAULT_SPEED >0){
                        this.setX(getX()- DEFAULT_SPEED);
                    }else {
                        this.setState(DEATH);
                        break outer;
                    }
                    break;
                case RIGHT:
                    if(getX()+ DEFAULT_SPEED <WIDTH){
                        this.setX(getX()+ DEFAULT_SPEED);
                    }else {
                        this.setState(DEATH);
                        break outer;
                    }
                    break;
            }
            TankType origin = this.getOrigin();
            ArrayList<? extends Tank> tanks = origin==TankType.HERO? TankGame.getEnemies():TankGame.getPlayers();
//            synchronized (tanks){
            try {
                this.attack(getX(), getY(), getDirect(), tanks, origin);
            }catch (DeathException e){
                break;
            }
//            }
            count.incrementAndGet();
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                return;
            }
        }
    }
}
